package com.mida.app.report.controller;

import com.mida.app.report.process.DocReportProcess;
import com.mida.bms.report.vo.*;
import com.mida.tool.common.result.ActionResult;
import com.mida.tool.common.result.ListResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

import static com.mida.tool.common.result.BaseResult.buildActionWarn;
import static com.mida.tool.common.result.BaseResult.buildListWarn;

/**
 * <h1>报告书写</h1>
 * <p>
 *
 * </p>
 *
 * @author jian.li on 2021/4/27 16:37
 */
@RestController
@RequestMapping("/docReport")
@CrossOrigin
@Slf4j
public class DocReportController {

    @Autowired
    private DocReportProcess docReportProcess;

    /**
     * 1.初始化模板报告
     *
     * @param docReportInitializationRequest 初始化模板报告请求参数
     * @return
     */
    @PostMapping("/initialize")
    @ResponseBody
    public ListResult<ReportInitializationResult> initializeDocReport(@RequestBody DocReportInitializationRequest docReportInitializationRequest,HttpServletRequest httpServletRequest) {
        return docReportProcess.initializeDocReport(docReportInitializationRequest,httpServletRequest);
    }

    /**
     * 2.暂存报告
     *
     * @param request 暂存报告请求参数
     * @return
     */
    @PostMapping("/saveTeporarily")
    @ResponseBody
    public ListResult<ReportResult> saveTemporarily(@RequestBody DocReportPreservationRequest request, HttpServletRequest httpServletRequest) {
        ListResult stringListResult = new ListResult<>();
        try {
            return docReportProcess.saveTemporarily(request,httpServletRequest);
        } catch (Exception e) {
            log.error("暂存报告失败", e);
            buildListWarn(stringListResult, "暂存报告失败");
        }
        return stringListResult;
    }

    /**
     * 3.签署报告
     * <p>
     * 共保存三份:
     * 1.json
     * 2.pdf
     * 3.结构化报告
     *
     * @param request 保存报告请求参数
     * @return
     */
    @PostMapping("/saveDocReport")
    @ResponseBody
    public ListResult<String> saveDocReport(@RequestBody DocReportPreservationRequest request, HttpServletRequest httpServletRequest) {
        ListResult stringListResult = new ListResult<>();
        log.info("开始保存报告");
        StopWatch stopWatch = StopWatch.createStarted();
        try {
            return docReportProcess.saveDocReport(request,httpServletRequest);
        } catch (Exception e) {
            log.error("签署报告失败", e);
            buildListWarn(stringListResult, "签署报告失败");
        }finally {
            stopWatch.stop();
            log.info("本次保存报告耗时: " + stopWatch.getTime() + "ms");
        }
        return stringListResult;
    }

    /**
     * 4.报告(初写完成待审核)编辑/撤回
     *
     * @param stReportSoid 报告存储信息标识
     * @return
     */
    @PostMapping("/editDocReport")
    @ResponseBody
    public ActionResult editDocReport(@RequestParam("stReportSoid") Long stReportSoid,HttpServletRequest httpServletRequest) {
        ActionResult actionResult = new ActionResult();
        try{
            return docReportProcess.editDocReport(stReportSoid,httpServletRequest);

        } catch (Exception e) {
            log.error("撤回报告发送异常", e);
            buildActionWarn(actionResult, "撤回报告失败");
        }
        return actionResult;
    }

    /**
     * 5.报告回显
     *
     * @param request 报告回显请求参数
     * @return
     */
    @PostMapping("/getDocReport")
    @ResponseBody
    public ListResult<ReportResult> getDocReport(@RequestBody DocReportInitializationRequest request,HttpServletRequest httpServletRequest) {
        return docReportProcess.getDocReport(request,httpServletRequest);
    }

    /**
     * 6.业务态保存报告模板
     *
     * @param request
     * @return
     */
    @PostMapping("/saveTemplate")
    @ResponseBody
    public ActionResult saveTemplate(@RequestBody DocReportPreservationRequest request,HttpServletRequest httpServletRequest) {
        return docReportProcess.saveTemplate(request,httpServletRequest);
    }

    /**
     * 7.接收报告，将报告改为已审核，保存报告
     *
     * @param reportRequest
     * @return
     */
    @PostMapping("/modifyReportStatus")
    @ResponseBody
    public ActionResult modifyReportStatus(@RequestBody DocReportPreservationRequest reportRequest,HttpServletRequest httpServletRequest) {
        ActionResult actionResult = new ActionResult();
        try {
            return  docReportProcess.modifyReportStatus(reportRequest, httpServletRequest);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            actionResult.setMessage("审核报告处理失败");
            actionResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return actionResult;
        }
    }


    /**
     * 8.退回报告，将报告改为审核已退回
     *
     * @param stReportSoid
     * @return
     */
    @GetMapping("/modifyStatus")
    @ResponseBody
    public ActionResult modifyStatus(String stReportSoid,HttpServletRequest httpServletRequest) {
        ActionResult actionResult = new ActionResult();
        try {
            return docReportProcess.modifyStatus(stReportSoid,httpServletRequest);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            actionResult.setMessage("退回报告处理失败");
            actionResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return actionResult;
        }

    }


    /**
     * 8.报告通过审核，撤回报告
     *
     * @param stReportSoid
     * @return
     */
    @GetMapping("/withdrawStatus")
    @ResponseBody
    public ActionResult withdrawStatus(@RequestParam("stReportSoid") String stReportSoid) {
        ActionResult actionResult = new ActionResult();
        try {
            return docReportProcess.withdrawStatus(stReportSoid);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            actionResult.setMessage("撤回报告处理失败");
            actionResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return actionResult;
        }
    }


    /**
     * 10.保存报告pdf文件
     *
     * @param stReportSoid 报告存储信息标识
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/savePdf")
    @ResponseBody
    public ActionResult savePdf(@RequestParam("stReportSoid") Long stReportSoid, @RequestParam("file") MultipartFile file,HttpServletRequest httpServletRequest) {
        return docReportProcess.savePdf(stReportSoid, file,httpServletRequest);
    }


    /**
     * 11.保存结构化报告
     *
     * @param request
     * @return
     */
    @PostMapping("/saveStructuredReport")
    @ResponseBody
    public ActionResult saveStructuredReport(@RequestBody StructuredReportRequest request,HttpServletRequest httpServletRequest) {
        return docReportProcess.saveStructuredReport(request,httpServletRequest);
    }

//    /**
//     * 12.根据不同的报告书写类型，登记号，检查号，申请单号保存报告
//     */
//    @PostMapping("/saveDocReportTypes")
//    @ResponseBody
//    public ListResult saveDocReportTypes(@RequestBody DocReportPreservationRequest docReportRequest,HttpServletRequest httpServletRequest) {
//        ListResult listResult = new ListResult();
//        try {
//            return docReportService.saveDocReportTypes(docReportRequest,httpServletRequest);
//        } catch (Exception ex) {
//            log.error(ex.getMessage(), ex);
//
//            listResult.setMessage("getPatientInfo处理失败");
//            listResult.setStatus(HttpStatus.BAD_REQUEST.value());
//            return listResult;
//        }
//
//    }

    /**
     * 13.根据登记号，检查号签署报告
     */
    @PostMapping("/saveDocReportByRegistrationAndExam")
    @ResponseBody
    public ListResult<String> saveDocReportByRegistrationAndExam(@RequestBody DocReportPreservationRequest request,HttpServletRequest httpServletRequest) {
        log.info("开始签署报告");
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult listResult = new ListResult();
        try {
            return docReportProcess.saveDocReportByRegistrationAndExam(request,httpServletRequest);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            listResult.setMessage("签署报告处理失败");
            listResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return listResult;
        }finally {
            stopWatch.stop();
            log.info("本次签署报告耗时: " + stopWatch.getTime() + "ms");
        }


    }

    /**
     * 14.根据申请单标识，登记标识，检查号 报告回显
     *
     * @param request 报告回显请求参数
     * @return
     */
    @PostMapping("/getDocReportByTypes")
    @ResponseBody
    public ListResult<ReportResult> getDocReportByTypes(@RequestBody DocReportInitializationRequest request,HttpServletRequest httpServletRequest) {
        ListResult listResult;
        try {
            return docReportProcess.getDocReportByTypes(request,httpServletRequest);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            listResult = new ListResult();
            listResult.setMessage("报告回显处理失败");
            listResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return listResult;
        }

    }

    /**
     * 15.根据申请单，登记单，检查单号初始化模板报告
     *
     * @param docReportInitializationRequest 初始化模板报告请求参数
     * @return
     */
    @PostMapping("/initializeDocReportTypes")
    @ResponseBody
    public ListResult<ReportInitializationResult> initializeDocReportTypes(@RequestBody DocReportInitializationRequest docReportInitializationRequest,HttpServletRequest httpServletRequest) {
        ListResult listResult;
        try {
            return docReportProcess.initializeDocReportTypes(docReportInitializationRequest,httpServletRequest);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            listResult = new ListResult();
            listResult.setMessage("初始化模板报告失败");
            listResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return listResult;
        }

    }

    /**
     * 16.根据申请单号，登记单号，检查号暂存报告
     *
     * @param request 暂存报告请求参数
     * @return
     */
    @PostMapping("/saveTemporarilyTypes")
    @ResponseBody
    public ListResult<ReportResult> saveTemporarilyTypes(@RequestBody DocReportPreservationRequest request,HttpServletRequest httpServletRequest) {
        ListResult listResult = new ListResult();
        try {
            return docReportProcess.saveTemporarilyTypes(request,httpServletRequest);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            listResult.setMessage("暂存报告处理失败");
            listResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return listResult;
        }

    }

    /**
     * 17.根据StReportSoid从docReportRequisitionRelation表中查询全部列表
     * @return
     */
    @PostMapping(value = "/selectByStReportSoid")
    @ResponseBody
    public List<DocReportRequisitionRelationVo> selectByStReportSoid(@RequestParam("stReportSoid") Long stReportSoid) {
        return docReportProcess.selectByStReportSoid(stReportSoid);
    }


    /**
     * 10.获取报告pdf
     *
     * @param request
     * @return
     */
    @PostMapping("/getReportPdf")
    @ResponseBody
    public void getReportPdf(@RequestBody ReportSearchRequest request, HttpServletResponse httpServletResponse){
        docReportProcess.getReportPdf(request,httpServletResponse);
    }

    /**
     * 20.获取报告pdfurl
     *
     * @param request
     * @return
     */
    @PostMapping("/getReportPdfUrl")
    @ResponseBody
    public ListResult<String> getReportPdfUrl(@RequestBody ReportSearchRequest request){
        ListResult listResult = new ListResult();
        try {
            return docReportProcess.getReportPdfUrl(request);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            listResult.setMessage("获取报告pdfurl失败");
            listResult.setStatus(HttpStatus.BAD_REQUEST.value());
            return listResult;
        }
    }

    /**
     * 发布报告(支持批量)
     *
     * @param reportPublishRequest 发布报告请求参数
     * @return
     */
    @PostMapping(value = "/publishReport")
    @ResponseBody
    public ActionResult publishReport(@RequestBody ReportPublishRequest reportPublishRequest,HttpServletRequest httpServletRequest){
        return docReportProcess.publishReport(reportPublishRequest,httpServletRequest);
    }

    /**
     * 召回报告
     *
     * @param reportRecallRequest 召回报告请求参数
     * @return
     */
    @PostMapping(value = "/recallReport",consumes = {"application/json"})
    @ResponseBody
    public ActionResult recallReport(@RequestBody ReportRecallRequest reportRecallRequest,HttpServletRequest httpServletRequest){
        return docReportProcess.recallReport(reportRecallRequest,httpServletRequest);
    }

    /**
     * 获取审核发布参数
     *
     * @return
     */
    @GetMapping(value = "/getReviewPublishParam",produces = {"application/json"})
    @ResponseBody
    public ListResult getReviewPublishParam(){
        return docReportProcess.getReviewPublishParam();
    }

    /**
     * 获取报告召回时间控制配置
     *
     * @return
     */
    @GetMapping(value = "/getRecallLimit",produces = {"application/json"})
    @ResponseBody
    public ListResult getRecallLimit(){

        return docReportProcess.getRecallLimit();
    }
    /**
     * 19.根据报告soid查询报告
     *
     * @param stReportSoid 报告soid
     * @return
     */
    @PostMapping(value = "/getDocReportByStReportSoid")
    @ResponseBody
    public ListResult<ReportResult> getDocReportByStReportSoid(@RequestParam("stReportSoid") Long stReportSoid) {
        return docReportProcess.getDocReportByStReportSoid(stReportSoid);
    }

    /**
     * 保存并转发危急值到代理(网关)
     *
     * @param request
     * @return
     */
    @PostMapping(value = "/saveCriticValue",consumes = {"application/json"})
    @ResponseBody
    public ListResult<Long> saveCriticValue(@RequestBody CriticalValueRequest request){
        return docReportProcess.saveCriticValue(request);
    }
}